<!DOCTYPE html>
<html>
<!-- 
  snabbdom: 
    是一个简洁，高性能的vdom lib。 vue2.x的vdom和diff就是完全参考它的。
    也就说，我们就学习snabbdom的vdom和diff是一样的。snabbdom中的代码比较简单。
    面试时，面试是的原理。只需要把原理说清楚就OK了。 了解了snabbdom的diff算法，就相当于了解了vue3.x中的diff算法了。

  去github上下载源码：
    1）科学上网 去github上下载。
    2）cdn  

  使用过程：
    https://juejin.cn/post/6844903767473651720



 -->

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="container"></div>
  <button id="btn-change">change</button>

  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom.js"></script>
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-class.js"></script>
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-props.js"></script>
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-style.js"></script>
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-eventlisteners.js"></script>
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/h.js"></script>
  <script>
    // console.log(window);
    const snabbdom = window.snabbdom;

    // 定义patch函数 非常重要
    // 功能：patch函数将newVnode更新到oldVnode或elem上。
    // 初次渲染是没有所谓的oldVnode
    // 首次渲染调用patch，都是更新到dom容器节点。
    // 当数据变了，生成新的vnode，新旧vnode需要对比，只去更新差异
    // path的过程，就是diff的过程，只不初次渲染不需要diff.
    let patch = snabbdom.init([
      snabbdom_class,
      snabbdom_props,
      snabbdom_style,
      snabbdom_eventlisteners
    ])

    // 定义h函数
    // 功能：是一个工厂函数，根据传入的参数，生成vnode结构
    const h = snabbdom.h;

    const container = document.getElementById("container");

    // 生成vnode 虚拟dom 
    // function h(sel,data:vnodeData,children:VnodeChild)
    const vnode = h('ul#list', {}, [
      h('li.item', {}, "Item 1"),
      h('li.item', {}, "Item 2")
    ]);

    // 初次渲染，就是把vnode，转化成真实dom,挂载到容器节点上。
    // 这个过程没有新旧vnode对比。
    patch(container, vnode);

    document.getElementById("btn-change").addEventListener("click", () => {
      // 生在newVnode
      const newVnode = h('ul#list', {}, [
        h('li.item', {}, "Item 1"),
        h('li.item', {}, "Item B"),
        h('li.item', {}, "Item 3")
      ]);
      // 此时新旧vnode开始对比，找到差异，更新差异
      patch(vnode,newVnode)
    })

  </script>
</body>

</html>